Shader Languages

SPIR-V

GLSL (OpenGL Shader Language)

Slang

WGSL (WebGPU)

  • Modern, safe, and cross-platform (WebGPU standard).

  • Works in browsers (WebGPU) and native (via wgpu ).

  • No corporate lock-in (developed by W3C & Mozilla/Google/Apple).

  • Newer, less mature than GLSL/SPIR-V.

  • "Explicitly designed to avoid C++/OOP cruft. Rust-inspired syntax but purely for GPU work."

~HLSL (High-level Shader Language)

  • HLSL .

  • Proprietary to Microsoft.

  • Made for DirectX 9.

  • HLSL programs come in six forms: pixel shaders (fragment in GLSL), vertex shaders, geometry shaders, compute shaders, tessellation shaders (Hull and Domain shaders), and ray tracing shaders.

  • Where it can be used :

    • Is mainly used in DirectX-based environments  (Windows/Xbox games, Unity, Unreal Engine). If you're targeting other platforms (macOS, Linux, mobile), you might need to use GLSL, MSL, or SPIR-V instead.

    • Direct3D (DirectX)

      • DirectX 9/10/11/12: HLSL is the standard shading language for Microsoft's Direct3D API.

      • Used in:

        • PC games (Windows)

        • Xbox console development (Xbox One, Xbox Series XS)

    • Unity (via Direct3D)

      • Unity supports HLSL when using:

        • Built-in Render Pipeline (Legacy)

        • Universal Render Pipeline (URP)

        • High Definition Render Pipeline (HDRP)

      • Shader Graph in Unity also uses HLSL-like syntax.

    • Unreal Engine (UE4/UE5)

      • Unreal Engine uses a custom shading language (Unreal Shader System, USS) but allows HLSL snippets in Custom HLSL Nodes.

      • HLSL is also used in Ray Tracing shaders in UE5.

    • NVIDIA OptiX (Ray Tracing)

      • HLSL can sometimes be used alongside CUDA/PTX for ray tracing effects.

    • Vulkan (via SPIR-V Cross)

      • HLSL shaders can be converted to SPIR-V (Vulkan's intermediate format) using tools like:

        • glslangValidator (from Khronos)

        • DXC (DirectX Shader Compiler)

        • SPIRV-Cross (converts HLSL to GLSL/SPIR-V)

    • Shader Model 6.0+ (Advanced Features)

      • HLSL supports modern GPU features like:

        • Ray Tracing (DXR)

        • Mesh & Amplification Shaders

        • Wave Operations.

    • Compute Shaders

      • (GPGPU programming in DirectX).

    • AI/ML Acceleration

      • (Some frameworks allow HLSL-based compute shaders for GPU acceleration).

  • Where it's not used :

    • OpenGL / WebGL β†’ Uses GLSL instead.

    • Vulkan (Native) β†’ Uses GLSL or SPIR-V.

    • Metal (Apple) β†’ Uses MSL (Metal Shading Language).

  • Ex :

    // Vertex Shader
    struct VSInput {
        float3 position : POSITION;
        float3 color : COLOR;
    };
    
    struct VSOutput {
        float4 position : SV_POSITION;
        float3 color : COLOR;
    };
    
    VSOutput VS_main(VSInput input) {
        VSOutput output;
        output.position = float4(input.position, 1.0);
        output.color = input.color;
        return output;
    }
    
    // Fragment Shader
    struct PSInput {
        float4 position : SV_POSITION;
        float3 color : COLOR;
    };
    
    float4 PS_main(PSInput input) : SV_TARGET {
        return float4(input.color, 1.0);
    }
    
  • Comparing the syntax of HLSL to GLSL :

    • Inputs :

      • HLSL:

        • The parameter for the VS_main  and PS_main  describe the inputs for each step.

        • Uses a struct with semantics ( : POSITION , : COLOR ).

      • GLSL:

        • Uses in / out  variables.

        • Uses layout(location)  to bind vertex attributes.

    • Outputs :

      • HLSL:
        Returns a struct, for passing values from the Vertex Shader to the Fragment Shader; VSOutput .

      • GLSL:

        • Uses a out  variable.

MSL (Metal Shading Language)

  • Apple’s official shader language (optimized for M1/M2).

  • Required for iOS/macOS Metal apps.

  • Apple-only (no Windows/Linux).

  • Use with MoltenVK if you want Vulkan β†’ Metal compatibility.

  • Ex :

    // Vertex Shader
    #include <metal_stdlib>
    using namespace metal;
    
    struct VertexIn {
        float3 position [[attribute(0)]];
        float3 color [[attribute(1)]];
    };
    
    struct VertexOut {
        float4 position [[position.md]];
        float3 color;
    };
    
    vertex VertexOut vertex_main(VertexIn in [[stage_in]]) {
        VertexOut out;
        out.position = float4(in.position, 1.0);
        out.color = in.color;
        return out;
    }
    
    // Fragment Shader
    fragment float4 fragment_main(VertexOut in [[stage_in]]) {
        return float4(in.color, 1.0);
    }